﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace UCF.Core.MathEx
{
    /// <summary>
    /// 排列组合
    /// </summary>
    public class Combination
    {
        /// <summary>
        /// 获取排列组合数量
        /// </summary>
        /// <param name="data"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public int GetCombinationCount(ref string[] data, int n)
        {
            if (n < 2) return 1;
            int i = data.Length;
            if (n == i) return 1;
            if (n > data.Length) return 0;
            int a1 = 1, a2 = 1;
            while (n > 0)
            {
                a1 *= i;
                a2 *= n;
                i--;
                n--;
            }
            return a1 / a2;
        }
        /// <summary>
        /// 排列组合运算
        /// </summary>
        /// <param name="data"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public IList<string> C(ref string[] data, int n)
        {
            switch (n)
            {
                case 2:
                    return C2(ref data);
                case 3:
                    return C3(ref data);
                case 4:
                    return C4(ref data);
                case 5:
                    return C5(ref data);
                case 6:
                    return C6(ref data);
                case 7:
                    return C7(ref data);
                case 8:
                    return C8(ref data);
                    
            }
            return new List<string>();
        }
        /// <summary>
        /// 组合2排列运算
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private IList<string> C2(ref string[] data)
        {
            IList<string> list = new List<string>();
            int l = data.Length;
            for (int i = 0; i < l; i++)
            {
                for (int i2 = i + 1; i2 < l; i2++)
                {
                    list.Add(string.Format("{0},{1}", data[i], data[i2]));
                }
            }
            return list;
        }
        /// <summary>
        /// 组合3排列运算
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private IList<string> C3(ref string[] data)
        {
            IList<string> list = new List<string>();
            int l = data.Length;
            for (int i = 0; i < l; i++)
            {
                for (int i2 = i + 1; i2 < l; i2++)
                {
                    for (int i3 = i2 + 1; i3 < l; i3++)
                    {
                        list.Add(string.Format("{0},{1},{2}", data[i], data[i2], data[i3]));
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 组合4排列运算
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private IList<string> C4(ref string[] data)
        {
            IList<string> list = new List<string>();
            int l = data.Length;
            for (int i = 0; i < l; i++)
            {
                for (int i2 = i + 1; i2 < l; i2++)
                {
                    for (int i3 = i2 + 1; i3 < l; i3++)
                    {
                        for (int i4 = i3 + 1; i4 < l; i4++)
                        {
                            list.Add(string.Format("{0},{1},{2},{3}", data[i], data[i2], data[i3], data[i4]));
                        }
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 组合5排列运算
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private IList<string> C5(ref string[] data)
        {
            IList<string> list = new List<string>();
            int l = data.Length;
            for (int i = 0; i < l; i++)
            {
                for (int i2 = i + 1; i2 < l; i2++)
                {
                    for (int i3 = i2 + 1; i3 < l; i3++)
                    {
                        for (int i4 = i3 + 1; i4 < l; i4++)
                        {
                            for (int i5 = i4 + 1; i5 < l; i5++)
                            {
                                list.Add(string.Format("{0},{1},{2},{3},{4}", data[i], data[i2], data[i3], data[i4], data[i5]));
                            }
                        }
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 组合6排列运算
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private IList<string> C6(ref string[] data)
        {
            IList<string> list = new List<string>();
            int l = data.Length;
            for (int i = 0; i < l; i++)
            {
                for (int i2 = i + 1; i2 < l; i2++)
                {
                    for (int i3 = i2 + 1; i3 < l; i3++)
                    {
                        for (int i4 = i3 + 1; i4 < l; i4++)
                        {
                            for (int i5 = i4 + 1; i5 < l; i5++)
                            {
                                for (int i6 = i5 + 1; i6 < l; i6++)
                                {
                                    list.Add(string.Format("{0},{1},{2},{3},{4},{5}", data[i], data[i2], data[i3], data[i4], data[i5], data[i6]));
                                }
                            }
                        }
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 组合7排列运算
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private IList<string> C7(ref string[] data)
        {
            IList<string> list = new List<string>();
            int l = data.Length;
            for (int i = 0; i < l; i++)
            {
                for (int i2 = i + 1; i2 < l; i2++)
                {
                    for (int i3 = i2 + 1; i3 < l; i3++)
                    {
                        for (int i4 = i3 + 1; i4 < l; i4++)
                        {
                            for (int i5 = i4 + 1; i5 < l; i5++)
                            {
                                for (int i6 = i5 + 1; i6 < l; i6++)
                                {
                                    for (int i7 = i6 + 1; i7 < l; i7++)
                                    {
                                        list.Add(string.Format("{0},{1},{2},{3},{4},{5},{6}", data[i], data[i2], data[i3], data[i4], data[i5], data[i6], data[i7]));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 组合8排列运算
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private IList<string> C8(ref string[] data)
        {
            IList<string> list = new List<string>();
            int l = data.Length;
            for (int i = 0; i < l; i++)
            {
                for (int i2 = i + 1; i2 < l; i2++)
                {
                    for (int i3 = i2 + 1; i3 < l; i3++)
                    {
                        for (int i4 = i3 + 1; i4 < l; i4++)
                        {
                            for (int i5 = i4 + 1; i5 < l; i5++)
                            {
                                for (int i6 = i5 + 1; i6 < l; i6++)
                                {
                                    for (int i7 = i6 + 1; i7 < l; i7++)
                                    {
                                        for (int i8 = i7 + 1; i8 < l; i8++)
                                        {
                                            list.Add(string.Format("{0},{1},{2},{3},{4},{5},{6},{7}", data[i], data[i2], data[i3], data[i4], data[i5], data[i6], data[i7],data[i8]));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return list;
        }
    }
}
